package top.vanchor.flexible.utils;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Ding
 * @create 2021/11/10 13:03
 */

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import top.vanchor.flexible.config.initexception.BusinessException;
import top.vanchor.flexible.config.initexception.ErrorEnum;
import top.vanchor.flexible.config.jwtconfig.JwtConfigProperties;

import java.util.Date;
import java.util.Objects;

public class JWTUtils {
    /**
     * 校验token是否正确
     *
     * @param token 密钥
     * @return 是否正确
     */
    public static boolean verify(String token, JwtConfigProperties jwtConfigProperties) throws Exception {
        try {
            Algorithm algorithm = Algorithm.HMAC256(jwtConfigProperties.getSecret());
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (TokenExpiredException tokenExpiredException) {
            throw new BusinessException(ErrorEnum.PARSING_FAILED);
        } catch (SignatureVerificationException signatureVerificationException) {
            // token验证失败
            throw new BusinessException(ErrorEnum.SIGNATURE_VERIFICATION);
        } catch (JWTDecodeException jwtDecodeException) {
            // token解析失败
            throw new BusinessException(ErrorEnum.DECODE_ERROR);
        } catch (Exception exception) {
            throw new BusinessException(ErrorEnum.NOT_LOGIN);
        }

    }

    /**
     * 获得token中的信息无需secret解密、更无须传入token也能获得
     *
     * @return token中包含的authorId
     */
    public static Integer getAuthorId() {
        //对JWT解密
        try {
            DecodedJWT jwt = JWT.decode(JwtInterceptor.getTokenInfo());
            return Integer.valueOf(Objects.requireNonNull(jwt.getClaim("id").asString()));
        } catch (NullPointerException e) {
            throw new BusinessException(ErrorEnum.NOT_LOGIN);
        }
    }

    /**
     * 获得token中的信息无需secret解密、更无须传入token也能获得
     *
     * @return token中包含的type（1：管理员，0用户）
     */
    public static String getAuthorType() {
        //对JWT解密
        try {
            DecodedJWT jwt = JWT.decode(JwtInterceptor.getTokenInfo());
            return Objects.requireNonNull(jwt.getClaim("type").asString());
        } catch (NullPointerException e) {
            return "<Unknown Type>";
        }
    }

    /**
     * 获得token中的信息无需secret解密、更无须传入token也能获得
     *
     * @return token中包含的type（1：管理员，0用户）
     */
    public static String getAuthorName() {
        //对JWT解密
        String authorName = "";
        try {
            DecodedJWT jwt = JWT.decode(JwtInterceptor.getTokenInfo());
            authorName = Objects.requireNonNull(jwt.getClaim("authorName").asString());
        } catch (NullPointerException e) {
            authorName = "<Unknown Name>";
        }
        return authorName;
    }

    /**
     * 获取token中的信息无需secret解密、更无须传入token也能获得
     *
     * @return token中包含的type类型名（1：管理员，0用户）
     */
    public static String getAuthorTypeName() {
        String authorTypeName = "";
        try {
            DecodedJWT jwt = JWT.decode(JwtInterceptor.getTokenInfo());
            authorTypeName = Integer.parseInt(Objects.requireNonNull(jwt.getClaim("type").asString())) == 1 ? "管理员" : "用户";
        } catch (NullPointerException e) {
            authorTypeName = "<Unknown Type>";
        }
        return authorTypeName;
    }

    public static long getExpire() {
        return new JwtConfigProperties().getExpire();
    }

    public static String getToken() {
        return JwtInterceptor.getTokenInfo();
    }

    /**
     * 生成签名,xxx后过期（配置文件）
     *
     * @param id   用户id
     * @param type 基本角色：0用户，1管理员
     * @return 加密的token
     */
    public static String sign(String id, String type, String authorName, JwtConfigProperties jwtConfigProperties) {
        Date date = new Date(System.currentTimeMillis() + jwtConfigProperties.getExpire());
        Algorithm algorithm = Algorithm.HMAC256(jwtConfigProperties.getSecret());
        // 附带userId信息
        return JWT.create()
                .withClaim("id", id)
                .withClaim("type", type)
                .withClaim("authorName", authorName)
                .withExpiresAt(date)
                .sign(algorithm);
    }

    public static Integer getAuthorIdByToken(String token) {
        //对JWT解密
        try {
            DecodedJWT jwt = JWT.decode(token);
            return Integer.valueOf(Objects.requireNonNull(jwt.getClaim("id").asString()));
        } catch (NullPointerException e) {
            throw new BusinessException(ErrorEnum.NOT_LOGIN);
        }
    }
}